<?php


namespace app\common\model;

use app\common\lib\RespCode;
use map\BaiDu;
use map\GaoDe;
use oss\Oss;
use think\Db;
use think\Exception;
use think\Model;

class BaseModel extends Model {
    const STATUS_ZERO = 0;
    const STATUS_ONE = 1;
    const STATUS_TWO = 2;
    const STATUS_THREE = 3;
    const STATUS_FOUR = 4;

    /**
     * 修改时不需要比对项
     * @var array
     */
    protected $noSubField = [
        'itime',
        'utime'
    ];

    protected $data = [];

    /**
     * @var 自定义表名
     */
    protected $customName;

    /**
     * 旧数据对比新数据
     * @param $old
     * @param $data
     * @return $this
     * @throws Exception
     */
    protected function subData($old) {
        foreach ($this->data as $key => $val) {
            if (!isset($this->noSubField[$key]) && isset($old[$key]) && $old[$key] == $val) {
                unset($this->data[$key]);
            }
        }

        if (empty($this->data)) {
            throw new Exception('未修改数据', RespCode::UP_DATA_EMPTY);
        }

        return $this;
    }

    /**
     * 高德地图-获取详细信息
     * @param $address
     * @param string $city
     * @return array
     * @throws Exception
     */
    //    public function getAddressInfoByMap($address, $city = '') {
    //        $res = GaoDe::getByAddress($address, $city);
    //        list($lng, $lat) = explode(',', $res['geocodes'][0]['location']);
    //        return [
    //            'province'  => $res['geocodes'][0]['province'],
    //            'city'      => $res['geocodes'][0]['city'],
    //            'area'      => $res['geocodes'][0]['district'],
    //            'district'  => $res['geocodes'][0]['street'],
    //            'address'   => $res['geocodes'][0]['formatted_address'],
    //            'city_code' => $res['geocodes'][0]['adcode'],
    //            'lng'       => $lng,
    //            'lat'       => $lat,
    //        ];
    //    }

    /**
     * 百度地图-获取详细信息
     * @param $address 詳細地址
     * @param $lat 纬度
     * @param $lng 经度
     * @param string $city
     * @return array
     * @throws Exception
     */
    public function getAddressInfoByMap($address, $lat, $lng, $city = '') {
        empty($lat) && $lat = 0;
        empty($lng) && $lng = 0;
        // 通过标题信息获取经纬度
        $res1 = BaiDu::getByAddress($address, $city);
        if (!empty($res1['result']['location']['lng']) && !empty($res1['result']['location']['lat'])) {
            $lat = $res1['result']['location']['lat'];
            $lng = $res1['result']['location']['lng'];
        }

        // 通过经纬度获取地址信息
        if ($lat > 0 && $lng > 0) {
            $res2 = BaiDu::getByLocation($lat, $lng);
            if (!empty($res2['result'])) {
                $lng = round($res2['result']['location']['lng'] ?? $lng, 6);
                $lat = round($res2['result']['location']['lat'] ?? $lat, 6);
                return [
                    'province'    => $res2['result']['addressComponent']['province'] ?? '',
                    'city'        => $res2['result']['addressComponent']['city'] ?? '',
                    'area'        => $res2['result']['addressComponent']['district'] ?? '',
                    'district'    => $res2['result']['addressComponent']['street'] ?? '',
                    'map_address' => $res2['result']['formatted_address'],
                    'city_code'   => $res2['result']['addressComponent']['adcode'] ?? 0,
                    'lng'         => $lng,
                    'lat'         => $lat,
                    'location'    => "POINT({$lng}, {$lat})",
                ];
            }
        }


        return [
            'location' => "POINT({$lng}, {$lat})",
            'lng'      => $lng,
            'lat'      => $lat,
        ];
    }

    /**
     * 批量上传图片到OSS
     * @param $filePaths
     * @param $prefix
     * @return string
     * @throws Exception
     */
    public function batchUpFileByOss($filePaths, $prefix) {
        $filenames = [];
        $filePaths = explode(',', $filePaths);
        if (empty($filePaths)) {
            return [];
        }
        foreach ($filePaths as $filePath) {
            $filenames[] = $this->upFileByOss($filePath, $prefix);
        }
        return $filenames;
    }

    /**
     * 上传图片到OSS
     * @param $filePath
     * @param $prefix
     * @return bool|string
     * @throws Exception
     */
    public function upFileByOss($filePath, $prefix) {
        if (empty($filePath)) {
            return '';
        }

        if (!is_file($filePath)) {
            return '';
        }
        $oss = Oss::getInstance();
        $filename = $oss->createFilename($prefix, get_ext($filePath));
        if ($oss->uploadFile($filePath)) {
            return $filename;
        }
        return false;
    }

    /**
     * 自定义表名
     * @param $name
     * @return $this
     */
    public function customName($name) {
        $this->customName = $name;
        return $this;
    }

    /**
     * 自定义修改sql语句
     * @param $data
     * @param string $where
     * @return int
     */
    public function customUpdate($data, $where) {
        $sql1 = "select COLUMN_NAME as field from information_schema.COLUMNS where table_name = '{$this->customName}'";
        $fields = Db::query($sql1);
        $fields = array_flip(array_column($fields, 'field'));
        $str = '';
        foreach ($data as $key => $val) {
            if (isset($fields[$key])) {

                if (strpos($val, 'POINT(') === false) {
                    $str = $str == '' ? "`{$key}` = '{$val}'" : "{$str},`{$key}` = '{$val}'";
                } else {
                    $str = $str == '' ? "`{$key}` = {$val}" : "{$str},`{$key}` = {$val}";
                }
            }
        }

        $sql = "update {$this->customName} set {$str} where {$where}";
        return db::execute($sql);
    }

    /**
     * 自定义插入sql语句
     * @param $data
     * @return int
     */
    public function customInsert($data) {
        $sql1 = "select COLUMN_NAME as field from information_schema.COLUMNS where table_name = '{$this->customName}'";
        $fields = Db::query($sql1);
        $fields = array_flip(array_column($fields, 'field'));
        $keys = $value = '';
        foreach ($data as $key => $val) {
            if (isset($fields[$key])) {
                $keys = $keys == '' ? "{$key}" : "{$keys},{$key}";
                if (strpos($val, 'POINT(') === false) {
                    $value = $value == '' ? "'{$val}'" : "{$value},'{$val}'";
                } else {
                    $value = $value == '' ? "{$val}" : "{$value},{$val}";
                }

            }
        }

        $sql = "insert into {$this->customName} ({$keys}) VALUES ({$value})";
        if (db::execute($sql) > 0) {
            $id = db::query("SELECT LAST_INSERT_ID()");
            if (!empty($id)) {
                return $id[0]['LAST_INSERT_ID()'];
            }
        }
        return false;
    }
}
